﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Windows.Data;
using SoftSource.Common;
using SoftSource.Timecard.Entry.ViewModelInterfaces;
using SoftSource.Timecard.Web.Data;

namespace SoftSource.Timecard.Entry.ViewModels
{
    public sealed class EntryEditorViewModel : IEntryEditorViewModel
    {
        #region Fields
        private Filter<CategorySummary> categoryFilter;
        private Filter<ProjectSummary> projectFilter;
        #endregion

        #region IEntryEditorViewModelConsume Members
        private PagedCollectionView projects;
        public PagedCollectionView Projects
        {
            get { return this.projects; }
            set
            {
                this.projects = value;
                this.projects.SortDescriptions.Add(new SortDescription(
                    ObjectReflection.GetPropertyName<ProjectSummary>(p => p.Name),
                    ListSortDirection.Ascending));

                this.AttachProjectFilter();

                this.PropertyChanged.Notify(() => this.Projects);
            }
        }

        private PagedCollectionView categories;
        public PagedCollectionView Categories
        {
            get { return this.categories; }
            set
            {
                this.categories = value;
                this.categories.SortDescriptions.Add(new SortDescription(
                    ObjectReflection.GetPropertyName<CategorySummary>(c => c.Name),
                    ListSortDirection.Ascending));

                //this.AttachCategoryFilter();

                this.PropertyChanged.Notify(() => this.Categories);
            }
        }

        private EntryLog entry;
        public EntryLog Entry
        {
            get { return this.entry; }
            set
            {
                this.entry = value;                
                this.PropertyChanged.Notify(() => this.Entry);
            }
        }

        private void AttachProjectFilter()
        {
            this.projectFilter = this.projects.AttachFilter<ProjectSummary>();
            this.projectFilter.Add(p => p.StatusID == ProjectStatus.Active);
        }

        private void AttachCategoryFilter()
        {
            this.categoryFilter = this.categories.AttachFilter<CategorySummary>();
            this.categoryFilter.Add(c => c.IsActive);
            this.categoryFilter.Add(c =>
                this.ProjectCategories
                .Where(pc => this.Entry != null)
                .Where(pc => pc.ProjectID == this.Entry.ProjectID)
                .Any(pc => pc.CategoryID == c.CategoryID));
        }

        public IObservable<Unit> Save { get; set; }

        #endregion

        #region IEntryEditorViewModelService Members

        public IEnumerable<ProjectCategorySummary> ProjectCategories { get; set; }

        private IEnumerable<ProjectSummary> projectSource;
        public IEnumerable<ProjectSummary> ProjectSource
        {
            get { return this.projectSource; }
            set
            {
                this.projectSource = value;
                this.Projects = new PagedCollectionView(this.projectSource);
            }
        }

        private IEnumerable<CategorySummary> categorySource;
        public IEnumerable<CategorySummary> CategorySource
        {
            get { return this.categorySource; }
            set
            {
                this.categorySource = value;
                this.Categories = new PagedCollectionView(this.categorySource);
            }
        }

        public IObservable<Unit> Load { get; set; }

        #endregion

        #region INotifyPropertyChanged Members


        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion

        ~EntryEditorViewModel()
        {
            this.Dispose();
        }

        #region IEditorConsume Members

        public Action Cancel { get; set; }

        public IObservable<Unit> Apply { get; set; }

        public Action<Exception> Failure { get; set; }

        #endregion
    }
}
